#include <cstring>
#include <cmath>
#include <iostream>  //预处理器指令 a PREPROCESSOR directive

#include <vector>
#include <array>
#include <new>
#include <valarray>

using namespace std; // 使定义可见   make definitions visible



/*
    模版类

        把 typedef unsigned long Item;
        替换为 
        template <class Type> / template<typename Type>  //定义一个模板。

        typedef这种方法有两个缺点：
        首先，每次修改类型时都需要编辑头文件；
        其次，在每个程序中只能使用这种技术生成一种栈，即不能让typedef同时代表两种不同的类型，因此不能使用这种方法在同一个程序中同时定义int栈和string栈。

        模板提供参数化(parameterized)类型，即能够将类型名作为参数传递给接收方来建立类或函数。


*/


template <class Type>
class Stack
{
private:
    enum {MAX = 10};    // constant specific to class
    Type items[MAX];    // holds stack items
    int top;            // index for top stack item

public:
    Stack();

    bool isempty();

    bool isfull();
    
    // push() returns false if stack already is full, true otherwise
	//如果堆栈已满，则返回false，否则返回true
    bool push(const Type & item); // add item to stack
    
    // pop() returns false if stack already is empty, true otherwise
	// pop（）如果堆栈已经为空，则返回false，否则返回true    
    bool pop(Type & item);        // pop top into item
};


template <class Type>
Stack<Type>::Stack()
{
    top = 0;
}

template <class Type>
bool Stack<Type>::isempty()
{
    return top == 0;
}

template <class Type>
bool Stack<Type>::isfull()
{
    return top == MAX;
}

template <class Type>
bool Stack<Type>::push(const Type & item)
{
    if (top < MAX)
    {
        items[top++] = item;
        return true;
    }
    else
        return false;
}

template <class Type>
bool Stack<Type>::pop(Type & item)
{
    if (top > 0)
    {
        item = items[--top];
        return true;
    }
    else
        return false; 
}



int main(){
    Stack<int> kernels;//create a stack of ints
    Stack<string> colonels;//create a stack of string objects

    kernels.push(1);
    kernels.push(2);

    int p = 20;
    kernels.pop(p);
    cout << "取出: " << p << endl;

}















